package com.hp.java12_springsecurity.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;

/**
 * WebSecurity配置
 */
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private PersistentTokenRepository persistentTokenRepository;

    /**
     * 返回密码编码器
     */
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    /**
     * 用于配置用户的账号、密码和角色、权限
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//        //在内存中配置用户
//        auth.inMemoryAuthentication()
//                .withUser("chenheng") //配置账号
//                .password(new BCryptPasswordEncoder().encode("123")) //配置加密后的密码
//                .roles("admin","user")//配置角色
//                .and() //配置另一个用户
//                .withUser("user")
//                .password(new BCryptPasswordEncoder().encode("123"))
//                .authorities("ROLE_user","select"); //权限
        //配置用户验证和授权为自定义的实现
        auth.userDetailsService(userDetailsService);
    }

    /**
     * 配置页面的授权
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests() //对请求进行授权
            .antMatchers("/login","/error","/js/**","/**/*.css").permitAll() //前面的url放行
            .antMatchers("/admin/**").hasRole("管理员") //配置url需要的角色
            .antMatchers("/user/**").hasAuthority("销售管理")
            .anyRequest().authenticated() //除了前面配置的url外，全部都要进行登录验证
            .and()
            .formLogin() //配置登录相关
            .loginPage("/login") //登录页面
//            .loginProcessingUrl("/login")
            .defaultSuccessUrl("/toMain") //登录成功后跳转的页面url
            .and()
            .logout().logoutUrl("/logout") //配置注销，必须post提交
            .logoutSuccessUrl("/login")
            .and().rememberMe()//记住我，配置
            .tokenRepository(persistentTokenRepository)
            .tokenValiditySeconds(60)
            .rememberMeParameter("rememberMe");
//            .and() //禁用跨域攻击防御,否则登录提交失败
//                .csrf().disable();
    }
}
